home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
pwrclib.exe
/
GLBL_ENV.C
< prev
next >
Wrap
Text File
|
1993-01-03
|
10KB
|
333 lines
/* I have adapted Clay Davis' modification of Peter Thomas' adaptation
of David Dubois' BASIC routines found on CompuServe. (whew!) Believe
it or not, the Microsoft C version compiled and ran WITHOUT ERROR
and WITHOUT MODIFICATION under Power C 2.2.0. I have included these
functions in my CJSLIB function library, and am indebted to the above
mentioned individuals for their willingness to share their techniques.
Chuck Steenburgh [72330,1776] */
/*****************************************************************************
This is a version of GLBL.ARC which was slightly modified to be used
in Microsoft-C. The following changes were made:
1. All calls to _farmalloc were replaced with _fmalloc
2. All calls to _farfree were replaced with _ffree
3. MS-C does not have an _mk_fp function which converts a pointer to
a far pointer. So, this task was done by multiplying the segment by
0x10000 to shift the pointer.
Other than these changes (Isn't C portable), the routine runs as stated
in the MS-C medium model. Other models should work also.
Modified by Clay Davis 76346,101 on July 11, 1988. Tested using MS-C 5.1.
************************************************************************
This code is based upon the program SETPATH.PAS (located in BPROGA) by
David Dubois [71401,747]
This Turbo C version is written by Peter Thomas [75716,2377]
This series of routines are designed to Locate, Retrieve, Update, and
Remove "Variables" from the MASTER copy of the DOS Environment table.
The routines have been written in a manner that avoids linking any
EXTERNAL routines for string manipulation, and thus should be independent
of memory model being used.
Be careful that changes made to the Environment with these routines
ONLY OCCUR IN THE MASTER COPY, and that if COMMAND.COM is spawned
from a routine that has changed the environment, NO CHANGES WILL BE
SEEN IN THE ENVIRONMENT. This is most apparent when this program is run
in the INTEGRATED environment: changes made by this technique will
not appear if the "OS Shell" is invoked, and will only appear on exit
from TC.
For full documentation on the techniques used here can be found in the
file COMENV.ARC located in LIB 2 of BPROGA on Compuserve.
As David Dubois says:
I hereby dedicate this knowledge to the public domain. Feel free to use
it, but if you do, please mention my name. There are no guarantees, and
in fact, I wouldn't bet a dollar that it will work every time.
That this works at all is based on experimental, rather than properly
documented, evidence. There are no guarantees. But then, its free.
*****************************************************************************/
#include <dos.h>
#include <stdio.h> /* MS-C requires this */
#include <stdlib.h> /* MS-C requires this */
#include <malloc.h> /* MS-C uses this instead of alloc.h */
/*
* Mstr_FindEnvironment:
* Scans for the "Master" Environment area, and returns
* a pointer to it, and the size of the environment.
*/
void Mstr_FindEnvironment ( char far **Env , unsigned *EnvSize )
{
unsigned int far *CommandSeg, far *TempSeg ;
char far *BlockSeg ;
/*
* Scan through PSP's looking for a block that is its own father.
* This block is the PSP of COMMAND.COM
*/
TempSeg = _psp*0x10000; /* Convert to a far pointer, replaces MK_FP */
do
{
CommandSeg = TempSeg ;
TempSeg = *(TempSeg+8)*0x10000; /* Replaces MK_FP in turbo C */
}
while ( TempSeg != CommandSeg ) ;
/*
* Scan forward through memory looking for the correct MSB.
* This will have COMMAND.COM's PSP as owner, and begin with
* the character M
*/
BlockSeg = (char far *)CommandSeg ;
do
{
BlockSeg = (FP_SEG(BlockSeg)+1)*0x10000; /* Replaces MK_FP */
}
while ( ( *(unsigned int far *)(BlockSeg+1) != FP_SEG ( CommandSeg ) ) ||
( *BlockSeg != 'M' ) ) ;
/*
* The environment is the NEXT segment of memory
* and bytes 4 and 5 are the size in paragraphs
*/
*Env = (FP_SEG(BlockSeg)+1)*0x10000; /* Replaces MK_FP */
*EnvSize = 16 * *(unsigned int far *)(BlockSeg+3) ;
}
/*
* Mstr_getenv:
* Scans the "Master" Environment for a given "sub string"
* and returns a pointer to it.
* Similar to Turbo routine "getenv" but uses the Master copy of the
* environment table.
*/
char far *Mstr_getenv (char far *Env , char far *name)
{
char far *Sub_Env, far *str1, far *str2 ;
/*
* Start at the beginning of the environment
*/
Sub_Env = Env ;
/*
* While the "sub string" we're looking at is non-zero
*/
for ( ; *Sub_Env ; )
{
/*
* Simulate a "strcmp" on the "sub string" of the environment
* and the string we're looking for
*/
for ( str1 = Sub_Env , str2 = name ;
(*str1) && (*str2) && ( *str1 == *str2) ;
str1++ , str2++ ) ;
/*
* If we reached the end of the string we're looing for
* we've found the correct portion of the environment.
* Return the ptr to the start of this "sub string"
*/
if ( !*str2 )
return ( Sub_Env ) ;
/*
* Otherwise, advance to the next "sub string" in the environment
* by performing a "strchr" function
*/
for ( ; *(Sub_Env++) ; ) ;
}
/*
* Obviously, the string is not present in the environment.
* Return this fact.
*/
return ( NULL ) ;
}
/*
* Mstr_delenv:
* Scans the "Master" Environment for a given "sub string"
* and removes it.
*/
int Mstr_delenv (char far *Env , unsigned EnvSize , char far *name)
{
char far *Sub_Env , far *New_Env ;
char huge *Dest , far *Src , huge *End_Env ;
int Done ;
unsigned Ctr ;
/*
* Allocate a chunk of storage to act as a "working" copy of
* the Environment table
*/
New_Env = _fmalloc ( EnvSize ) ;
/*
* Copy the data from the Master to Working copy of the
* Environment table.
* Simulates a "memcpy" function.
*/
for ( Src = Env , Dest = (char far *)New_Env , Ctr = 0 ;
Ctr < EnvSize ;
*(Dest++) = *(Src++) , Ctr++ ) ;
/*
* Scan the working copy of the environment for the desired
* sub string
*/
Sub_Env = Mstr_getenv ( New_Env , name ) ;
if ( Sub_Env == NULL )
{
/*
* If not found, do nothing
*/
Done = -1 ;
} else {
/*
* Locate the end of the string to delete
* Simulate a "strchr" call
*/
for ( Src = Sub_Env ; *(Src++) ; ) ;
/*
* Move the rest of the environment back over the "sub string"
* being deleted.
* Simulated "memcpy" function.
* Huge pointers used for pointer comparison purposes.
*/
for ( Dest = (char huge *)Sub_Env , End_Env = (char huge *) (New_Env + EnvSize ) ;
( Dest < End_Env ) ;
*(Dest++) = *(Src++) ) ;
/*
* Copy the data from the Working to Master copy of the
* Environment table.
* Simulates a "memcpy" function.
*/
for ( Src = New_Env , Dest = (char huge *)Env , Ctr = 0 ;
Ctr < EnvSize ;
*(Dest++) = *(Src++) , Ctr++ ) ;
/*
* Signal all done
*/
Done = 0 ;
}
/*
* Free all working storage
*/
_ffree ( New_Env ) ;
return ( Done ) ;
}
/*
* Mstr_putenv:
* Adds/Replaces a given "sub string" in the Master Environment.
* Similar to Turbo routine "putenv" but uses the Master copy of the
* environment table.
*/
int Mstr_putenv (char far *Env , unsigned EnvSize , char far *name )
{
char far *Sub_Env , far *Temp_Name ;
char huge *Dest , far *Src , huge *End_Env ;
int Done ;
/*
* Allocate a chunk of storage to create the Variable name